#include "autotrace.h"
#include "message.h"
#include "cmdline.h"
#include "logreport.h"
#include "getopt.h"
#include "filename.h"
#include "xstd.h"
#include "atou.h"
#include "strgicmp.h"
#include "input.h"

#include <assert.h>
#include <math.h>

// NDK -----------------------------------------------
#include <jni.h>
#include <string.h>
#include <android/log.h>

#include <unistd.h>

#define DEBUG_TAG "AUTOTRACE"

void Java_autotrace_Autotrace_staticMethod(JNIEnv * env)
{
	LOG("it is working");
}

void dumpToFile(const char* fileName, const char* buffer, int bufsize)
{
	FILE* dumpFile = fopen(fileName, "w");
	int leftToWrite = bufsize;
	const char* pos = buffer;
	int written;
	do
	{
		written = fwrite(pos, 1, leftToWrite, dumpFile);
		pos += written;
		leftToWrite -= written;
	} while (written != 0 && leftToWrite >= 0);
	fclose(dumpFile);
}

void Java_autotrace_Autotrace_traceMat(JNIEnv * env,
		jlong jdataAddr,
		jint jwidth,
		jint jheight,
		jstring jfileName,
		jstring jfileExt)
{
	jboolean isCopy;
	const char * output = (*env)->GetStringUTFChars(env, jfileName, &isCopy);
	const char * extension = (*env)->GetStringUTFChars(env, jfileExt, &isCopy);

	// pointer to the internal byte array of the openCV Mat
	long long dataAddr = jdataAddr;
	// cast the 64 bit address to a 32 bit pointer
	unsigned char* bytes = (unsigned char*) dataAddr;

	unsigned short width = (unsigned short) jwidth;
	unsigned short height = (unsigned short) jheight;
	unsigned int count = width * height;

	at_fitting_opts_type * opts = at_fitting_opts_new();
	opts->centerline = true;

	at_bitmap_type image = at_bitmap_init(bytes, width, height, 3);
	at_splines_type * splines = at_splines_new(&image, opts, NULL, NULL);

	int i;
	for (i = 0; i < splines->length; ++i)
	{
		// for every spline
		LOG2("i: %u   l: %u\n", i, splines->data[i].length);
		int j;
		for (j = 0; j < splines->data[i].length; ++j)
		{
			// for every ?
			LOG3("\tj: %u   d: %u  linearity %f\n", j,
					splines->data[i].data[j].degree,
					splines->data[i].data[j].linearity);
			int k;
			for (k = 0; k < 4; ++k)
			{
				LOG3("\t\tk: %u x %f y %f\n", k,
						splines->data[i].data[j].v[k].x,
						splines->data[i].data[j].v[k].y);
			}
		}
	}

	// create a handler for the output format (DXF)
	at_output_write_func wfunc = at_output_get_handler_by_suffix(extension);
	FILE* f = fopen(output, "w");
	// write the vectorized image to a file
	at_splines_write(wfunc, f, "", NULL, splines, NULL, NULL);
	fclose(f);

}

void Java_autotrace_Autotrace_traceImage(JNIEnv * env,
		jstring inputFileJ,
		jstring outputFileJ,
		jstring outputFormatJ)
{
	jboolean isCopy;
	const char * input = (*env)->GetStringUTFChars(env, inputFileJ, &isCopy);
	const char * output = (*env)->GetStringUTFChars(env, outputFileJ, &isCopy);
	const char * extension = (*env)->GetStringUTFChars(env, outputFormatJ,
			&isCopy);

	// "/storage/sdcard0/code/face.bmp"
	char * fname = input;
	at_splines_type * splines;
	at_bitmap_type * bitmap;

	// fitting options. These are usually passed as command line parameters
	at_fitting_opts_type * opts = at_fitting_opts_new();

	// set the option to trace the centerline, not the outline. When tracing a drawing you would want to do this.
	opts->centerline = true;

	// create a handler for the particular image format (BMP)
	at_input_read_func rfunc = at_input_get_handler(fname);

	// create a handler for the output format (DXF)
	at_output_write_func wfunc = at_output_get_handler_by_suffix(extension);

	// read the raster image
	bitmap = at_bitmap_read(rfunc, fname, NULL, NULL, NULL);

	// vectorize the image
	splines = at_splines_new(bitmap, opts, NULL, NULL);

	LOG2("bbox: w: %u, h: %u\n", splines->width, splines->height);

	LOG1("length: %u\n", splines->length);

	int i;
	for (i = 0; i < splines->length; ++i)
	{
		// for every spline
		LOG2("i: %u   l: %u\n", i, splines->data[i].length);
		int j;
		for (j = 0; j < splines->data[i].length; ++j)
		{
			// for every ?
			LOG3("\tj: %u   d: %u  linearity %f\n", j,
					splines->data[i].data[j].degree,
					splines->data[i].data[j].linearity);
			int k;
			for (k = 0; k < 4; ++k)
			{
				LOG3("\t\tk: %u x %f y %f\n", k,
						splines->data[i].data[j].v[k].x,
						splines->data[i].data[j].v[k].y);
			}
		}
	}

	FILE* f = fopen(output, "w");
	// write the vectorized image to a file
	at_splines_write(wfunc, f, "", NULL, splines, NULL, NULL);
	fclose(f);
}

void Java_autotrace_Autotrace_helloLog(JNIEnv * env, jstring logThis)
{

	jboolean isCopy;

	const char * szLogThis = (*env)->GetStringUTFChars(env, logThis, &isCopy);

	__android_log_print(ANDROID_LOG_DEBUG, DEBUG_TAG, "NDK:LC: [%s]",
			szLogThis);

	(*env)->ReleaseStringUTFChars(env, logThis, szLogThis);

}

// NDK -----------------------------------------------
